package org.yinxianren.www.study_02.study.netty.bio;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.*;

public class TimeService {
    private int port=8080;
    private ServerSocket serverSocket=null;
    private Socket socket;


    public static void main(String[] args) {
        TimeService ts= new TimeService();
       try {
           ts.service(args);
       }catch (Exception e){
           e.printStackTrace();
       }
    }

    /**
     *
     * @param args
     */
    private void service(String[] args) throws IOException {

        try{

            if(args !=null &&  args.length>0)   port= Integer.valueOf(args[0]);
            serverSocket= new ServerSocket(port);
            while(true){
                System.out.println("【Service socket】 The service socket into while loop");
                socket=serverSocket.accept();
                System.out.println("【Service socket】 The service socket  begin start");
                //1.BIO 模式
//                new Thread(new TimeServerHandler(socket)).start();

                //2.伪NIO 模式
                TimeServerHandlerExecutePool tshe=new TimeServerHandlerExecutePool(5,5,120L,120);
                tshe.executor(new TimeServerHandler(socket));
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
              if(serverSocket != null){
                  System.out.println("【Service socket】 The time server close !");
                  serverSocket.close();
                  serverSocket= null;
              }
        }
    }
}

/**
 * 使用多线程处理客户端请求
 */
 class TimeServerHandler implements Runnable {

    private  Socket socket=null;
    private BufferedReader bufferedReader=null;
    private PrintWriter printWriter=null;

     /**
      *
      * @param socket
      */
    public TimeServerHandler(Socket socket) {
        this.socket=socket;
    }

     @Override
     public void run() {

         try {
             //模拟加载资源
             TimeUnit.SECONDS.sleep(3);
             System.out.println("【Service socket】Thread-Name:"+Thread.currentThread().getName());
             bufferedReader= new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
             printWriter=new PrintWriter(this.socket.getOutputStream(),true);
             String body=null;
             while(true){
                 body= bufferedReader.readLine();
                 if(null == body) break;
                 System.out.println("【Service socket】 the time server receive order :"+body);
                 String currentTime= "QUERY THE ORDER".equalsIgnoreCase(body) ?  new Date(System.currentTimeMillis()).toString(): "BAD ORDER";
                 printWriter.println(currentTime);
             }
         }catch (InterruptedException e) {
             e.printStackTrace();
         } catch (Exception e) {
//             e.printStackTrace();
         }finally {
             closeResource(bufferedReader,socket,printWriter);
         }
     }

    /**
     *
     * @return
     */
    private boolean closeResource(BufferedReader bufferedReader,Socket socket,PrintWriter printWriter){
        if(null != bufferedReader){
            try{
                bufferedReader.close();
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
        }

        if(null != printWriter){
            printWriter.close();
        }

        if(null != socket){
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
     }
 }

/**
 *  线程池
 */
class TimeServerHandlerExecutePool{

     private ExecutorService executorService=null;

     public TimeServerHandlerExecutePool(int corePoolSize,int maxPoolSize,Long keepAliveTime ,int queueSize){
//         public ThreadPoolExecutor(int corePoolSize,
//         int maximumPoolSize,
//         long keepAliveTime,
//         TimeUnit unit,
//         BlockingQueue<Runnable> workQueue)
         this.executorService=new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(queueSize));
     }

     public void executor(Runnable task){
         this.executorService.execute(task);
     }

 }